package top.lv666.graduation_design_serve.service;

import com.auth0.jwt.interfaces.DecodedJWT;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import top.lv666.graduation_design_serve.mapper.UserInfoMapper;
import top.lv666.graduation_design_serve.mapper.UserMapper;
import top.lv666.graduation_design_serve.pojo.Attention;
import top.lv666.graduation_design_serve.pojo.Blog;
import top.lv666.graduation_design_serve.pojo.User;
import top.lv666.graduation_design_serve.pojo.UserInfo;
import top.lv666.graduation_design_serve.util.CacheData;
import top.lv666.graduation_design_serve.util.JWTUtils;
import top.lv666.graduation_design_serve.util.SendPhoneMessage;
import top.lv666.graduation_design_serve.util.Tools;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Transactional
public class UserServiceImpl implements UserService {

    // 细粒度信息对调试应用非常有帮助，主要打印一些运行信息
    // logger.debug("logger的debug级别");
    // 粗粒度突出强调应用程序的运行过程，打印感兴趣或者重要的信息
    // logger.info("logger的info级别");
    // 表明会出现潜在错误的情形，有些信息不是错误信息，但也要给程序员一点提示
    // logger.warn("logger的warn级别");
    // 指出虽然发生错误，但不影响运行，打印错误和异常信息，如果不想输出太多日志可以使用该级别
    // logger.error("logger的error级别");
    // 每个严重的错误事件将会导致应用程序的退出，出现错误可以停止程序运行进行调试
    // logger.fatal("logger的fatal级别");

    // 通用map
    private Map<String, Object> paramsMap = new HashMap<>();

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private UserInfoMapper userInfoMapper;

    @Transactional(propagation = Propagation.SUPPORTS)

    /**
     * @apiNote 查询某个用户的详细信息
     * */
    @Override
    public UserInfo queryUserInfo(HttpServletRequest request) {
        Tools.isLogin(request);
        String id = Tools.getUserId(request);
        return userInfoMapper.queryLoginUserById(id);
    }


    /**
     * @apiNote 查询用户信息根据传入的ID
     */
    @Override
    public UserInfo queryUserInfoById(String id) {
        return userInfoMapper.queryLoginUserById(id);
    }

    /**
     * @apiNote 我关注了谁
     */
    @Override
    public List<UserInfo> selectMyFoucs(Map<String, Object> map) {
        HttpServletRequest request = (HttpServletRequest) map.get("request");
        map.remove("request");
        Tools.isMapNull(map);
        Tools.isLogin(request);
        String uId = Tools.getUserId(request);
        map.put("userId", uId);
        int getPage = (int) map.get("getPage");
        getPage = (getPage - 1) * (int) map.get("getNumber");
        map.put("getPage", getPage);
        List<Attention> attentionList = userInfoMapper.selectMyFocus(map);
        List<UserInfo> userInfoList = new ArrayList<>();
        for (Attention a : attentionList) {
            String id = a.getFollowedUserId();
            UserInfo uf = userInfoMapper.queryLoginUserById(id);
            userInfoList.add(uf);
        }
        return userInfoList;
    }

    /**
     * @apiNote 谁关注了我（我的粉丝）
     */
    @Override
    public List<UserInfo> selectMyFans(Map<String, Object> map) {
        HttpServletRequest request = (HttpServletRequest) map.get("request");
        map.remove("request");
        Tools.isMapNull(map);
        Tools.isLogin(request);
        String uId = Tools.getUserId(request);
        map.put("userId", uId);
        int getPage = (int) map.get("getPage");
        getPage = (getPage - 1) * (int) map.get("getNumber");
        map.put("getPage", getPage);
        List<Attention> attentionList = userInfoMapper.selectMyFans(map);
        List<UserInfo> userInfoList = new ArrayList<>();
        for (Attention a : attentionList) {
            String id = a.getUserId();
            UserInfo uf = userInfoMapper.queryLoginUserById(id);
            userInfoList.add(uf);
        }
        return userInfoList;
    }

    /**
     * @apiNote 关注某个用户
     */
    @Override
    public void focusOnUserById(Map<String, Object> map) {
        HttpServletRequest request = (HttpServletRequest) map.get("request");
        map.remove("request");
        Tools.isMapNull(map);
        Tools.isLogin(request);
        // 关注者ID
        String userId = Tools.getUserId(request);
        // 被关注者ID
        String followedUserId = (String) map.get("followedUserId");
        map.put("userId", userId);
        map.put("createTime", Tools.getTime());
        userInfoMapper.createAttentionById(map);

        // 修改关注者的关注人数
        paramsMap.clear();
        paramsMap.put("uId", userId);
        UserInfo userInfo = userInfoMapper.queryLoginUserById(userId);
        int focusNumber = Integer.parseInt(userInfo.getFocusNumber());
        System.out.println(focusNumber);
        focusNumber++;
        paramsMap.put("focusNumber", focusNumber);
        userInfoMapper.ModifyUserInfoById(paramsMap);

        // 修改关注者的粉丝数
        paramsMap.clear();
        paramsMap.put("uId", followedUserId);
        UserInfo userInfo1 = userInfoMapper.queryLoginUserById(followedUserId);
        int fansNumber = Integer.parseInt(userInfo1.getFocusNumber());
        fansNumber++;
        paramsMap.put("fansNumber", fansNumber);
        userInfoMapper.ModifyUserInfoById(paramsMap);
    }

    /**
     * @apiNote 用户登录验证
     */
    @Override
    public String selectOneUser(Map<String, Object> map) {
        HttpServletResponse response = (HttpServletResponse) map.get("response");
        map.remove("response");
        //判空
        Tools.isMapNull(map);
        HashMap<String, String> token = new HashMap<>();
        if (((String) map.get("passWord")).length() < 6 && ((String) map.get("userName")).length() < 10) {
            throw new Error("账号密码格式错误！");
        }
        User user = userMapper.selectOneUser(map);
        if (user == null || !user.getPassWord().equals(map.get("passWord"))) {
            throw new Error("账号/密码错误！");
        }
        if (user.getIsUserState().equals("3")) {
            throw new Error("账号已被封禁");

        }
        token.put("uId", user.getUId());
        response.addHeader("Access-Control-Expose-Headers", "Authorization");
        String authorization = JWTUtils.getToken(token);
        response.addHeader("Authorization", authorization);
        return user.getUId();
    }

    /**
     * @apiNote 用户注册
     */
    @Override
    public void createOneUser(Map<String, Object> map) {
        Tools.isMapNull(map);
        String uId = Tools.getUUID();
        map.put("uId", uId);
        map.put("updateTime", Tools.getTimer());
        map.put("createTime", Tools.getTimer());
        map.put("isUserState", 0);
        userMapper.createOneUser(map);
        //生成该账号的附属信息
        Map<String, Object> userInfo = new HashMap<>();
        userInfo.put("uId", uId);
        userInfo.put("nick", "用户_" + Tools.getRandomCode());
        userInfo.put("userCarId", Tools.getTimer() + Tools.getRandomCode());
        //生成附属账号
        userInfoMapper.createUserInfo(userInfo);
    }

    /**
     * @apiNote 查询用户是否被注册
     */
    @Override
    public boolean selectUserIsExits(String userName) {
        return userMapper.selectUserIsExist(userName) < 1;
    }

    /**
     * @apiNote 获取邮箱验证码
     */
    @Override
    public void getCode(Map<String, Object> map) {
        HttpServletRequest request = (HttpServletRequest) map.get("request");
        map.remove("request");
        String email = (String) map.get("userName");
        Tools.isMapNull(map);
        String code = String.valueOf(Tools.getRandomCode());
        //添加内存缓存
        CacheData.addCacheDate(Tools.getIpAddr(request), code, Tools.getTimer());
        //邮箱格式
        String str = "<div style='text-align:center'> <h1>激活码</h1>" +
                "<h2 style='color:red'>" + code + "</h2>" +
                "<div>非常感谢您使用我们的产品。【注意该验证码有效时间为5分钟！】</div></div>";
        try {
            Tools.SendQQMail("注册验证码", str, email);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * @apiNote 获取手机验证码
     */
    @Override
    public void getPhoneCode(Map<String, Object> map) {
        HttpServletRequest request = (HttpServletRequest) map.get("request");
        map.remove("request");
        Tools.isMapNull(map);
        long code = Tools.getRandomCode();
        String phone = (String) map.get("userName");
        //添加内存缓存
        CacheData.addCacheDate(Tools.getIpAddr(request), String.valueOf(code), Tools.getTimer());
        //发送手机验证码
        SendPhoneMessage.send("+86" + phone, String.valueOf(code));
    }

    /**
     * @apiNote 验证码登录
     */
    @Override
    public String phoneCodeLogin(Map<String, Object> map) {
        HttpServletRequest request = (HttpServletRequest) map.get("request");
        HttpServletResponse response = (HttpServletResponse) map.get("response");
        map.remove("request");
        map.remove("response");
        Tools.isMapNull(map);
        String code = (String) map.get("code");
        String ip = Tools.getIpAddr(request);
        HashMap<String, String> token = new HashMap<>();
        if (CacheData.checkCacheDate(ip, code)) {
            User user = userMapper.selectOneUser(map);
            if (user == null) {
                throw new Error("该账号还未注册！");
            }
            if (user.getIsUserState().equals("3")) {
                throw new Error("账号已被封禁");
            }
            token.put("uId", user.getUId());
            response.addHeader("Access-Control-Expose-Headers", "Authorization");
            String authorization = JWTUtils.getToken(token);
            response.addHeader("Authorization", authorization);
            //删除过期缓存
            CacheData.deleteCacheDate(ip);
            return user.getUId();
        } else {
            throw new Error("验证码错误！");
        }
    }

    /**
     * 注销用户
     */
    @Override
    public void killerUser(Map<String, Object> map) {
        //判断传值是否为空
        Tools.isMapNull(map);
    }

    /**
     * @apiNote 修改用户信息0.0-.-
     */
    @Override
    public void ModifyUserInfo(Map<String, Object> map) {
        HttpServletRequest request = (HttpServletRequest) map.get("request");
        //获取权限
        String str = request.getHeader("authorization");
        map.remove("request");
        Tools.isMapNull(map);
        //解析Token加密数据
        DecodedJWT jwt = JWTUtils.getTokenInfo(str);
        String uId = jwt.getClaims().get("uId").asString();
        map.put("uId", uId);
        if (JWTUtils.verify(str)) {
            userInfoMapper.ModifyUserInfoById(map);
        }
    }

    /**
     * @apiNote 获取高质量用户
     */
    @Override
    public List<Map<String, Object>> getHotUser(int page, int limit) {
        // 跳过多少行
        page = (page - 1) * limit;
        // 请求数据库
        List<UserInfo> userInfoList = userInfoMapper.queryHotUserInfo(page, limit);
        // 最后返回的数据数组
        List<Map<String, Object>> returnMap = new ArrayList<>();
        // 整合数据
        for (UserInfo u : userInfoList) {
            Map<String, Object> parmMap = new HashMap<>();
            parmMap.put("uId", u.getUId());
            parmMap.put("nick", u.getNick());
            parmMap.put("headerImg", u.getHeaderImg());
            returnMap.add(parmMap);
        }
        return returnMap;
    }

    /**
     * @param map
     * @apiNote 我赞了的博客
     */
    @Override
    public List<Blog> getLikeBlogById(Map<String, Object> map) {
        return null;
    }
}
